#pragma once

namespace gtl 
{

namespace type 
{

template<class T>
struct traits 
{
private:
	template<class U> struct value					{ typedef U			type; };
	template<class U> struct value<U&>				{ typedef U			type; };
	template<class U> struct value<const U&>		{ typedef U			type; };

	template<class U> struct ref					{ typedef U&		type; };
	template<class U> struct ref<U&>				{ typedef U&		type; };
	template<class U> struct ref<const U&>			{ typedef U&		type; };

	template<class U> struct const_ref				{ typedef const U&	type; };
	template<class U> struct const_ref<U&>			{ typedef const U&	type; };
	template<class U> struct const_ref<const U&>	{ typedef const U&	type; };

	template<class U> struct pointer				{ typedef U*		type; };
	template<class U> struct pointer<U&>			{ typedef U*		type; };
	template<class U> struct pointer<const U&>		{ typedef U*		type; };

	template<class U> struct const_pointer			{ typedef const U*	type; };
	template<class U> struct const_pointer<U&>		{ typedef const U*	type; };
	template<class U> struct const_pointer<const U&>{ typedef const U*	type; };

	template<class U> struct param					{ typedef U			type; };
	template<class U> struct param<U&>				{ typedef U&		type; };

public:
	typename typedef value<T>::type			value_type;
	typename typedef ref<T>::type			ref_type;
	typename typedef const_ref<T>::type		const_ref_type;

	typename typedef pointer<T>::type		pointer_type;
	typename typedef const_pointer<T>::type	const_pointer_type;

	typename typedef param<T>::type			param_type;
};

} // end of namespace type

} // end of namespace gtl